/**
 * 动态组件使用 Composable
 * 提供在页面中直接使用动态加载组件的功能
 */
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useModuleManager } from '@/modules/composables/useModuleManager'
import type { DynamicModule } from '@/modules/dynamic/types'

/**
 * 动态组件使用 Composable
 * 
 * 功能：
 * 1. 加载并获取动态组件
 * 2. 提供组件状态和错误处理
 * 3. 支持组件配置和属性传递
 * 4. 自动处理组件的生命周期
 */
export function useDynamicComponent(moduleId: string, options = {}) {
  const {
    autoLoad = true,
    defaultConfig = {},
    onError,
    onLoaded,
    onUnmounted
  } = options

  // 依赖注入
  const moduleManager = useModuleManager()

  // 响应式状态
  const component = ref<any>(null)
  const loading = ref(false)
  const error = ref<string | null>(null)
  const config = ref(defaultConfig)
  const isLoaded = ref(false)

  // 计算属性
  const moduleInfo = computed(() => moduleManager.getModule(moduleId))
  const moduleState = computed(() => moduleManager.getModuleState(moduleId))
  const isModuleAvailable = computed(() => !!moduleInfo.value)

  /**
   * 加载组件
   */
  const loadComponent = async (loadOptions = {}) => {
    if (!moduleId) {
      const errorMsg = 'Module ID is required'
      error.value = errorMsg
      onError?.(new Error(errorMsg))
      return
    }

    try {
      loading.value = true
      error.value = null

      // 检查模块是否可用
      if (!isModuleAvailable.value) {
        throw new Error(`Module ${moduleId} not found`)
      }

      // 加载模块
      const loadedComponent = await moduleManager.loadModule(moduleId, loadOptions)
      
      component.value = loadedComponent
      isLoaded.value = true
      
      console.log(`[useDynamicComponent] Component ${moduleId} loaded successfully`)
      onLoaded?.(moduleId, loadedComponent)
      
      return loadedComponent
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to load component'
      error.value = errorMessage
      console.error(`[useDynamicComponent] Failed to load component ${moduleId}:`, err)
      onError?.(err instanceof Error ? err : new Error(errorMessage))
      throw err
    } finally {
      loading.value = false
    }
  }

  /**
   * 卸载组件
   */
  const unloadComponent = async () => {
    if (!moduleId || !isLoaded.value) return

    try {
      await moduleManager.unloadModule(moduleId)
      component.value = null
      isLoaded.value = false
      error.value = null
      
      console.log(`[useDynamicComponent] Component ${moduleId} unloaded successfully`)
      onUnmounted?.(moduleId)
    } catch (err) {
      const errorMessage = err instanceof Error ? err.message : 'Failed to unload component'
      error.value = errorMessage
      console.error(`[useDynamicComponent] Failed to unload component ${moduleId}:`, err)
      onError?.(err instanceof Error ? err : new Error(errorMessage))
    }
  }

  /**
   * 重新加载组件
   */
  const reloadComponent = async (reloadOptions = {}) => {
    await unloadComponent()
    return await loadComponent(reloadOptions)
  }

  /**
   * 更新组件配置
   */
  const updateConfig = (newConfig: Record<string, any>) => {
    config.value = { ...config.value, ...newConfig }
  }

  /**
   * 重置组件状态
   */
  const resetComponent = () => {
    component.value = null
    loading.value = false
    error.value = null
    config.value = defaultConfig
    isLoaded.value = false
  }

  /**
   * 检查组件是否已加载
   */
  const checkComponentLoaded = () => {
    return moduleManager.isModuleLoaded(moduleId)
  }

  /**
   * 获取组件性能指标
   */
  const getPerformanceMetrics = () => {
    return moduleManager.getPerformanceMetrics(moduleId)
  }

  /**
   * 获取组件错误历史
   */
  const getErrorHistory = () => {
    return moduleManager.getErrorHistory(moduleId)
  }

  // 事件监听
  const handleModuleLoaded = (loadedModuleId: string, loadedComponent: any) => {
    if (loadedModuleId === moduleId) {
      component.value = loadedComponent
      isLoaded.value = true
      loading.value = false
      error.value = null
      onLoaded?.(moduleId, loadedComponent)
    }
  }

  const handleModuleError = (errorModuleId: string, err: Error) => {
    if (errorModuleId === moduleId) {
      error.value = err.message
      loading.value = false
      onError?.(err)
    }
  }

  const handleModuleUnloaded = (unloadedModuleId: string) => {
    if (unloadedModuleId === moduleId) {
      component.value = null
      isLoaded.value = false
      onUnmounted?.(moduleId)
    }
  }

  // 生命周期钩子
  onMounted(async () => {
    // 注册事件监听器
    moduleManager.on('module:loaded', handleModuleLoaded)
    moduleManager.on('module:error', handleModuleError)
    moduleManager.on('module:unloaded', handleModuleUnloaded)

    // 检查组件是否已经加载
    if (checkComponentLoaded()) {
      const loadedComponent = moduleManager.getModuleState(moduleId)?.component
      if (loadedComponent) {
        component.value = loadedComponent
        isLoaded.value = true
      }
    }

    // 自动加载组件
    if (autoLoad && !isLoaded.value) {
      await loadComponent()
    }
  })

  onUnmounted(() => {
    // 移除事件监听器
    moduleManager.off('module:loaded', handleModuleLoaded)
    moduleManager.off('module:error', handleModuleError)
    moduleManager.off('module:unloaded', handleModuleUnloaded)

    // 可选：自动卸载组件
    // await unloadComponent()
  })

  return {
    // 状态
    component,
    loading,
    error,
    config,
    isLoaded,
    
    // 计算属性
    moduleInfo,
    moduleState,
    isModuleAvailable,
    
    // 方法
    loadComponent,
    unloadComponent,
    reloadComponent,
    updateConfig,
    resetComponent,
    checkComponentLoaded,
    getPerformanceMetrics,
    getErrorHistory
  }
}

/**
 * 动态组件渲染器
 * 提供一个统一的组件渲染接口
 */
export function useDynamicComponentRenderer() {
  /**
   * 渲染动态组件
   */
  const renderDynamicComponent = (moduleId: string, props = {}, options = {}) => {
    const {
      loadingComponent = null,
      errorComponent = null,
      fallbackComponent = null
    } = options

    return {
      moduleId,
      props,
      loadingComponent,
      errorComponent,
      fallbackComponent
    }
  }

  return {
    renderDynamicComponent
  }
}

/**
 * 多组件管理器
 * 用于管理多个动态组件
 */
export function useMultipleDynamicComponents(moduleIds: string[], options = {}) {
  const {
    autoLoad = true,
    parallelLoad = true
  } = options

  const components = ref<Record<string, any>>({})
  const loadingStates = ref<Record<string, boolean>>({})
  const errorStates = ref<Record<string, string | null>>({})
  const loadedStates = ref<Record<string, boolean>>({})

  // 初始化状态
  moduleIds.forEach(moduleId => {
    components.value[moduleId] = null
    loadingStates.value[moduleId] = false
    errorStates.value[moduleId] = null
    loadedStates.value[moduleId] = false
  })

  /**
   * 加载单个组件
   */
  const loadSingleComponent = async (moduleId: string) => {
    const {
      component,
      loading,
      error,
      isLoaded
    } = useDynamicComponent(moduleId, {
      autoLoad: false,
      onLoaded: (id, comp) => {
        components.value[id] = comp
        loadedStates.value[id] = true
      },
      onError: (err) => {
        errorStates.value[moduleId] = err.message
      }
    })

    loadingStates.value[moduleId] = true
    errorStates.value[moduleId] = null

    try {
      await loadComponent()
      loadedStates.value[moduleId] = true
    } catch (err) {
      errorStates.value[moduleId] = err instanceof Error ? err.message : 'Failed to load'
    } finally {
      loadingStates.value[moduleId] = false
    }
  }

  /**
   * 加载所有组件
   */
  const loadAllComponents = async () => {
    if (parallelLoad) {
      // 并行加载
      const loadPromises = moduleIds.map(moduleId => loadSingleComponent(moduleId))
      await Promise.allSettled(loadPromises)
    } else {
      // 串行加载
      for (const moduleId of moduleIds) {
        await loadSingleComponent(moduleId)
      }
    }
  }

  /**
   * 获取组件状态
   */
  const getComponentStatus = (moduleId: string) => {
    if (loadingStates.value[moduleId]) return 'loading'
    if (errorStates.value[moduleId]) return 'error'
    if (loadedStates.value[moduleId]) return 'loaded'
    return 'unloaded'
  }

  // 自动加载
  onMounted(async () => {
    if (autoLoad) {
      await loadAllComponents()
    }
  })

  return {
    components,
    loadingStates,
    errorStates,
    loadedStates,
    loadSingleComponent,
    loadAllComponents,
    getComponentStatus
  }
}
